import DialogComponent from '@/components/Dialog/index.vue'
import { createVNode, h, render } from 'vue'

interface ButtonOption {
  text: string
  type?: 'primary' | 'default'
  onClick?: () => void
}

interface DialogOptions {
  title?: string
  content?: string
  contentTitle?: string
  contentSubTitle?: string
  buttons?: ButtonOption[]
  onClose?: () => void
}

// 创建一个容器来挂载动态创建的组件
let dialogContainer: HTMLElement | null = null

// 创建一个函数来获取或创建容器
function getContainer() {
  if (!dialogContainer) {
    dialogContainer = document.createElement('view')
    dialogContainer.id = 'dynamic-dialog-container'
    document.body.appendChild(dialogContainer)
  }
  return dialogContainer
}

// 创建一个函数来清理容器
function clearContainer() {
  if (dialogContainer) {
    render(null, dialogContainer)
  }
}

// 创建一个函数来显示对话框
function showDialog(options: DialogOptions): Promise<void> {
  return new Promise((resolve) => {
    // 在小程序环境中，我们需要使用不同的方式
    // #ifdef MP-WEIXIN
    uni.navigateTo({
      url: '/pages/common/dialog',
      events: {
        // 监听页面关闭事件
        close: () => {
          options.onClose?.()
          resolve()
        },
      },
      success: (res) => {
        // 通过 eventChannel 向打开页面传送数据
        res.eventChannel.emit('dialogOptions', options)
      },
    })
    // #endif

    // 在非小程序环境中，我们可以使用动态组件
    // #ifndef MP-WEIXIN
    const container = getContainer()

    // 创建按钮配置，确保每个按钮点击后都会关闭对话框
    const buttons = options.buttons?.map(btn => ({
      ...btn,
      onClick: () => {
        btn.onClick?.()
        // 关闭对话框
        // eslint-disable-next-line ts/no-use-before-define
        dialogInstance.exposed?.close()
        // 清理容器
        setTimeout(() => {
          clearContainer()
          options.onClose?.()
          resolve()
        }, 300) // 给动画一些时间
      },
    })) || []

    // 如果没有按钮，添加一个默认的确定按钮
    if (buttons.length === 0) {
      buttons.push({
        text: '确定',
        type: 'primary',
        onClick: () => {
          // 关闭对话框
          // eslint-disable-next-line ts/no-use-before-define
          dialogInstance.exposed?.close()
          // 清理容器
          setTimeout(() => {
            clearContainer()
            options.onClose?.()
            resolve()
          }, 300) // 给动画一些时间
        },
      })
    }

    // 创建 VNode
    const vnode = createVNode(DialogComponent, {
      title: options.title,
      buttons,
      ref: 'dialogRef',
    }, {
      'default': () => options.content ? h('view', {}, options.content) : null,
      'content-title': () => options.contentTitle ? h('view', {}, options.contentTitle) : null,
      'content-sub-title': () => options.contentSubTitle ? h('view', {}, options.contentSubTitle) : null,
    })

    // 渲染到容器
    render(vnode, container)

    // 获取组件实例
    const dialogInstance = vnode.component!

    // 打开对话框
    setTimeout(() => {
      dialogInstance.exposed?.open()
    }, 10)
    // #endif
  })
}

// 导出对话框函数
export const dialog = {
  show(options: DialogOptions) {
    return showDialog(options)
  },

  alert(content: string, options: Omit<DialogOptions, 'content' | 'buttons'> = {}) {
    return showDialog({
      ...options,
      content,
      buttons: [
        {
          text: '确定',
          type: 'primary',
        },
      ],
    })
  },

  confirm(content: string, options: Omit<DialogOptions, 'content'> = {}) {
    return new Promise<boolean>((resolve) => {
      let confirmed = false

      showDialog({
        ...options,
        content,
        buttons: options.buttons || [
          {
            text: '取消',
            type: 'default',
            onClick: () => {
              resolve(false)
            },
          },
          {
            text: '确定',
            type: 'primary',
            onClick: () => {
              confirmed = true
              resolve(true)
            },
          },
        ],
        onClose: () => {
          options.onClose?.()
          if (!confirmed) {
            resolve(false)
          }
        },
      })
    })
  },
}
